home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
c
/
nos042_s
/
ksubr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-16
|
7KB
|
247 lines
#include <stdio.h> /***/
#include <dos.h>
#include <setjmp.h>
/*
Machine or compiler-dependent portions of kernel
Atari ST / Lattice C 5.5 version - DFN
*/
#include "global.h"
#include "proc.h"
#include "commands.h"
static unsigned short oldNull;
static unsigned short *oldNullp;
static int stkutil(struct proc *pp);
void init_psetup(struct proc *pp);
struct JMP_BUF {
int jmp_d2;
int jmp_d3;
int jmp_d4;
int jmp_d5;
int jmp_d6;
int jmp_d7;
int jmp_pc;
int jmp_a2;
int jmp_a3;
int jmp_a4;
int jmp_a5;
int jmp_a6;
int jmp_a7;
};
void kinit(void)
{
/* Remember location 0 pattern to detect null pointer derefs */
#ifndef ATARI /* Access to location 0 causes bus error on ATARI */
oldNullp = NULL;
oldNull = *oldNullp;
#endif
}
/* Print process table info
* Since things can change while ps is running, the ready proceses are
* displayed last. This is because an interrupt can make a process ready,
* but a ready process won't spontaneously become unready. Therefore a
* process that changes during ps may show up twice, but this is better
* than not having it showing up at all.
*/
int
ps(int argc, char *argv[], void *p)
{
register struct proc *pp;
register struct JMP_BUF *ep;
unsigned short i;
tprintf("PID SP stksize maxstk event fl in out name\n");
for(pp = Susptab;pp != NULLPROC;pp = pp->next){
ep = (struct JMP_BUF *)&pp->env;
if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d %s\n",
pp, /* process */
ep->jmp_a7, /* stack pointer */
pp->stksize, /* stack size */
stkutil(pp), /* maxstk */
pp->event, /* event */
pp->i_state ? 'I' : ' ', /* flags */
(pp->state & WAITING) ? 'W' : ' ',
(pp->state & SUSPEND) ? 'S' : ' ',
pp->input, pp->output, /* input, output sockets */
pp->name) == EOF) /* name */
return 0;
}
for(i=0;i<PHASH;i++){
for(pp = Waittab[i];pp != NULLPROC;pp = pp->next){
ep = (struct JMP_BUF *)&pp->env;
if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d %s\n",
pp, /* process */
ep->jmp_a7, /* stack pointer */
pp->stksize, /* stack size */
stkutil(pp), /* maxstk */
pp->event, /* event */
pp->i_state ? 'I' : ' ', /* flags */
(pp->state & WAITING) ? 'W' : ' ',
(pp->state & SUSPEND) ? 'S' : ' ',
pp->input, pp->output,
pp->name) == EOF) /* name */
return 0;
}
}
for(pp = Rdytab;pp != NULLPROC;pp = pp->next){
ep = (struct JMP_BUF *)&pp->env;
if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d %s\n",
pp, /* process */
ep->jmp_a7, /* stack pointer */
pp->stksize, /* stack size */
stkutil(pp), /* maxstk */
pp->event, /* event */
pp->i_state ? 'I' : ' ', /* flags */
(pp->state & WAITING) ? 'W' : ' ',
(pp->state & SUSPEND) ? 'S' : ' ',
pp->input, pp->output,
pp->name) == EOF) /* name */
return 0;
}
if(Curproc != NULLPROC){
pp = Curproc;
if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d %s\n",
pp, /* process */
ep->jmp_a7, /* stack pointer */
pp->stksize, /* stack size */
stkutil(pp), /* maxstk */
pp->event, /* event */
pp->i_state ? 'I' : ' ', /* flags */
(pp->state & WAITING) ? 'W' : ' ',
(pp->state & SUSPEND) ? 'S' : ' ',
pp->input, pp->output,
pp->name) == EOF) /* name */
return 0;
}
return 0;
}
int stkutil(struct proc *pp)
{
unsigned int i;
int16 *sp;
i = pp->stksize;
for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
i--;
return (int) i;
}
/* Verify that stack pointer for current process is within legal limits;
* also check that no one has dereferenced a null pointer
*/
void
chkstk(void)
{
int16 *sbase;
int16 *stop;
int16 *sp = (int16 *) getreg(REG_A7); /* get current stack pointer */
/* this is Lattice C 5.0 specific */
sbase = Curproc->stack;
stop = sbase + Curproc->stksize;
if(sp < sbase || sp >= stop){
printf("Stack violation, process %s \n\n",Curproc->name);
printf("SP = %lx, legal stack range [%lx,%lx) \n\n",
sp, sbase, stop);
fflush(stdout);
killself();
}
#ifndef ATARI
if(*oldNullp != oldNull){
printf("WARNING: Location 0 smashed, process %s\n",Curproc->name);
*oldNullp = oldNull;
fflush(stdout);
}
#endif
}
/* Machine-dependent initialization of the initial task */
void
init_psetup(pp)
struct proc *pp;
{
/*
* The base of the stack that's allocated to this program by the
* Amiga operating system has been left for us in "base" by the
* C startup routine.
*/
extern int16 *_base;
register int i;
pp->stack = _base;
pp->stksize = (int16 *)getreg(REG_A7) - pp->stack;
/*
* Have to be careful here to only clear as much of the stack as we're
* not currently using.
*/
for (i=0; i<pp->stksize; i++)
pp->stack[i] = STACKPAT;
pp->stksize += 50; /* slop.. there is a way to find out what this
really is. */
setjmp(pp->env);
pp->i_state = 1;
}
/* Machine-dependent initialization of a task */
void
psetup(pp,iarg,parg1,parg2,pc)
struct proc *pp; /* Pointer to task structure */
int iarg; /* Generic integer arg */
void *parg1; /* Generic pointer arg #1 */
void *parg2; /* Generic pointer arg #2 */
void (*pc)(); /* Initial execution address */
{
register long *stktop;
register struct JMP_BUF *ep;
/* Set up stack to make it appear as if the user's function was called
* by killself() with the specified arguments. When the user returns,
* killself() automatically cleans up.
*
* First, push args on stack in reverse order, simulating what C
* does just before it calls a function.
*/
stktop = (long *)(pp->stack + pp->stksize);
/* NOTE: this only works when compiled with 32 bit integers */
*--stktop = (long) parg2;
*--stktop = (long) parg1;
*--stktop = (long) iarg;
/* Now push the entry address of killself(), simulating the call to
* the user function.
*/
*--stktop = (long) killself;
/* *--stktop = 0; */ /* fodder for longjmp() */
setjmp(pp->env);
ep = (struct JMP_BUF *)&pp->env;
ep->jmp_a7 = (long) stktop;
ep->jmp_pc = (long) pc;
ep->jmp_a4 = getreg(REG_A4);/* set-up base relative addressing
environment pointer */
/* ep->jmp_d1 = (long) iarg; */
/* ep->jmp_a1 = (long) parg1; */
ep->jmp_a2 = (long) parg2;
ep->jmp_a3 = (long) pp;
/* Task initially runs with interrupts on */
pp->i_state = 1;
}